package utils

import (
	"fmt"
	"image/color"
	"sync"

	"github.com/mojocn/base64Captcha"
)

var (
	captUtilTemp *captUtil
	store        *redisStore
	cKey         = "captCache:"
	captUtilOnce sync.Once
)

type captUtil struct{}

func NewCaptchaUtils() *captUtil {
	captUtilOnce.Do(func() {
		captUtilTemp = &captUtil{}
		store = &redisStore{}
	})
	return captUtilTemp
}

// Generate 生成验证码
func (m *captUtil) Generate() (id, b64s, answer string, err error) {

	// 创建一个图形验证码的驱动
	// driver := base64Captcha.NewDriverDigit(80, 240, 6, 0.7, 80)
	// 创建公式验证码的驱动
	bgColor := &color.RGBA{R: 255, G: 255, B: 255, A: 255}
	driver := base64Captcha.NewDriverMath(80, 240, 5, 3, bgColor, nil, []string{})
	captcha := base64Captcha.NewCaptcha(driver, store)

	return captcha.Generate()
}

// CaptchaVerify 校验验证码
func (m *captUtil) CaptchaVerify(id string, code string) bool {
	return store.Verify(id, code, true)
}

// 自定义RedisStore实现base64Captcha.Store接口
type redisStore struct{}

func (s *redisStore) Set(id string, value string) error {
	return rdCli.SetEx(cKey+id, value, 300)
}

func (s *redisStore) Get(id string, clear bool) string {
	val, err := rdCli.Get(cKey + id)
	if err != nil {
		return ""
	}
	if clear {
		rdCli.Del(cKey + id)
	}
	return fmt.Sprintf("%v", val) // 进行类型断言并转换为string类型
}

func (s *redisStore) Verify(id, answer string, clear bool) bool {
	val := s.Get(id, clear)
	return val == answer
}
